package ch.headshot.photomap.mapper;

import java.io.File;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;

import javax.xml.bind.JAXB;
import javax.xml.datatype.XMLGregorianCalendar;

import primer.po.GpxType;
import primer.po.LinkType;
import primer.po.TrkType;
import primer.po.TrksegType;
import primer.po.WptType;

public class MapperStrategy {

	private HashMap<String, WptType> data;
	private final GpxType gpx;
	private final int shiftMinutes;
	private final int tolerance = 60;

	public GpxType getGpx() {
		return gpx;
	}

	public int getShiftMinutes() {
		return shiftMinutes;
	}

	public int getTolerance() {
		return tolerance;
	}

	public MapperStrategy(File gpxInput, int shiftMinutes) {
		this.shiftMinutes = shiftMinutes;
		gpx = JAXB.unmarshal(gpxInput, GpxType.class);
		init();
	}

	private void init() {
		data = new HashMap<String, WptType>();
		for (TrkType trk : gpx.getTrk()) {
			for (TrksegType trkseg : trk.getTrkseg()) {
				for (WptType wpt : trkseg.getTrkpt()) {
					XMLGregorianCalendar time = wpt.getTime();
					int hour = time.getHour();
					int minute = time.getMinute();
					minute += shiftMinutes;
					while (minute < 0) {
						minute += 60;
						hour -= 1;
					}
					while (minute > 59) {
						minute -= 60;
						hour += 1;
					}
					data.put(generateKey(time.getYear(), time.getMonth(), time.getDay(), hour, minute), wpt);
				}
			}
		}
	}

	public WptType createWptForImage(File image) {
		Calendar cal = Calendar.getInstance();
		cal.setTimeInMillis(image.lastModified());
		Date date = new Date(image.lastModified());

		int year = cal.get(Calendar.YEAR);
		int month = date.getMonth() + 1;
		int day = cal.get(Calendar.DAY_OF_MONTH);
		int houre = cal.get(Calendar.HOUR_OF_DAY);
		int minute = cal.get(Calendar.MINUTE);

		WptType pt = null;
		int i = 0;
		while (pt == null && i < tolerance) {
			int minInc = minute + i;
			int hInc = houre;
			while (minInc > 59) {
				minInc = minInc - 60;
				hInc++;
			}
			String key = generateKey(year, month, day, hInc, minInc);
			pt = data.get(key);

			if (pt == null) {
				int minDec = minute - i;
				int hDec = houre;
				while (minDec < 0) {
					minDec = minDec + 60;
					hDec--;
				}
				key = generateKey(year, month, day, hDec, minDec);
				pt = data.get(key);
			}
			i++;
		}
		if (pt != null) {
			System.out.println("found coords for " + image.getName() + " with a tolerance of " + i);
			WptType wpt = new WptType();
			LinkType link = new LinkType();
			link.setHref(image.getName());
			wpt.setLat(pt.getLat());
			wpt.setLon(pt.getLon());

			wpt.getLink().add(link);
			return wpt;
		} else {
			System.out.println("no coords found for" + image.getName() + " " + year + " " + month + " " + day + " " + houre + " " + minute);
			return null;
		}

	}

	private String generateKey(int year, int month, int day, int houre, int minute) {
		StringBuilder sb = new StringBuilder();
		sb.append(year);
		sb.append(month);
		sb.append(day);
		sb.append(houre);
		sb.append(minute);
		return sb.toString();
	}

}
